package main

import "fmt"

func printSlice(s []int) {
	fmt.Printf("s=%v, len=%d, cap=%d\n", s, len(s), cap(s))
}

func main() {
	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
	fmt.Printf("arr=%v\n", arr)
	s1 := arr[2:6]
	s2 := s1[3:5]
	s3 := append(s2, 10)
	s4 := append(s3, 11)
	s5 := append(s4, 12)

	fmt.Println("arr=", arr) // {0, 1, 2, 3, 4, 5, 6, 10}  ***
	fmt.Println("s1=", s1)   //	      {2, 3, 4, 5}
	fmt.Println("s2=", s2)   //                 {5, 6}
	fmt.Println("s3=", s3)   //       {5, 6, 10}
	fmt.Println("s4=", s4)   //       {5, 6, 10, 11}
	fmt.Println("s5=", s5)   //       {5, 6, 10, 11, 12}

	var s []int // Zero value for slice is nil

	for i := 0; i < 100; i++ {
		// 添加元素时如果超越cap，系统会重新分配更大的底层数组
		// 由于值传递的关系，必须接收append的返回值
		// s = append(s, val)
		printSlice(s)
		s = append(s, 2*i+1)
	}
	fmt.Println(s)

	fmt.Println("Creating Slice")

	ss1 := []int{2, 4, 6, 8}
	printSlice(ss1) //s=[2 4 6 8], len=4, cap=4

	ss2 := make([]int, 16)
	ss3 := make([]int, 10, 32)
	printSlice(ss2) // s=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], len=16, cap=16
	printSlice(ss3) // s=[0 0 0 0 0 0 0 0 0 0], len=10, cap=32

	fmt.Println("Copying slice")
	copy(ss2, ss1)
	printSlice(ss2) // s=[2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0], len=16, cap=16

	fmt.Println("Deleting elements from slice")
	ss2 = append(ss2[:3], ss2[4:]...)
	printSlice(ss2) // s=[2 4 6 0 0 0 0 0 0 0 0 0 0 0 0], len=15, cap=16

	fmt.Println("Popping from front")
	front := ss2[0]
	ss2 = ss2[1:]
	fmt.Println(front) //  2
	printSlice(ss2)    // s=[4 6 0 0 0 0 0 0 0 0 0 0 0 0], len=14, cap=15

	fmt.Println("Popping from back")
	tail := ss2[len(ss2)-1]
	ss2 = ss2[:len(ss2)-1]
	fmt.Println(tail) // 0
	printSlice(ss2)   // s=[4 6 0 0 0 0 0 0 0 0 0 0 0], len=13, cap=15

}
